#ifndef __RAF_H__
#define __RAF_H__
#include "TXLib.h"

void FillBIH (BITMAPINFOHEADER& bi, BITMAP bmpScreen)
{
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmpScreen.bmWidth;
    bi.biHeight = bmpScreen.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = 24;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;
}

int SaveHDC(const char* filename, HDC dc, int width, int height)
{
    HDC hdcMemDC = CreateCompatibleDC(dc);

    if(!hdcMemDC)
    {
        MessageBox(NULL, "CreateCompatibleDC has failed", "Failed", MB_OK);
        DeleteObject(hdcMemDC);
        return 0;
    }

    // Create a compatible bitmap from the Window DC
    HBITMAP hbmScreen = CreateCompatibleBitmap(dc, width, height);

    if(!hbmScreen)
    {
        MessageBox(NULL, "CreateCompatibleBitmap Failed", "Failed", MB_OK);
        DeleteObject(hbmScreen);
        DeleteObject(hdcMemDC);
        return 0;
    }

    // Select the compatible bitmap into the compatible memory DC.
    SelectObject(hdcMemDC,hbmScreen);

    // Bit block transfer into our compatible memory DC.
    if(!BitBlt(hdcMemDC,
               0,0,
               width, height,
               dc,
               0,0,
               SRCCOPY))
    {
        MessageBox(NULL, "BitBlt has failed", "Failed", MB_OK);
        DeleteObject(hbmScreen);
        DeleteObject(hdcMemDC);
        return 0;
    }
    BITMAP bmpScreen = {};
    // Get the BITMAP from the HBITMAP
    GetObject(hbmScreen, sizeof(BITMAP) ,&bmpScreen);

    BITMAPFILEHEADER bmfHeader = {};
    BITMAPINFOHEADER bi = {};

    FillBIH(bi, bmpScreen);

    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

    // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
    // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
    // have greater overhead than HeapAlloc.
    HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
    char *lpbitmap = (char *)GlobalLock(hDIB);

    // Gets the "bits" from the bitmap and copies them into a buffer
    // which is pointed to by lpbitmap.
    GetDIBits(dc, hbmScreen, 0,
             (UINT)bmpScreen.bmHeight,
             lpbitmap,
             (BITMAPINFO *)&bi, DIB_RGB_COLORS);

    // A file is created, this is where we will save the screen capture.
    HANDLE hFile = CreateFile(filename,
                              GENERIC_WRITE,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL, NULL);

    // Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB;

    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM

    DWORD dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);

    //Unlock and Free the DIB from the heap
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);

    //Close the handle for the file that was created
    CloseHandle(hFile);

    //Clean up
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);

    return 1;
}

#endif
